package com.shijie.utlis;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shijie.constant.OtherExConstant;
import com.shijie.exception.OtherException;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class JsonUtils {

    private static final ObjectMapper jsonMapper = new ObjectMapper();

    /**
     * 获取唯一JSON操作的ObjectMapper实例
     */
    public static ObjectMapper ObjectMapperInstance4Json() {
        return jsonMapper;
    }

    /**
     * 将对象转为JSON数据
     */
    public static <T> String toJson(T obj) {
        try {
            String json = jsonMapper.writeValueAsString(obj);
            return json;
        } catch (JsonProcessingException e) {
            throw new OtherException(e.toString());
        }
    }

    /**
     * 将JSON字符串转为对象
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        try {
            T obj = jsonMapper.readValue(json, clazz);
            return obj;
        } catch (JsonProcessingException e) {
            throw new OtherException(e.toString());
        }
    }

    /**
     * 写JSON字符串到指定路径
     */
    public static <T> Path writeJson2FilePath(String dirs, String filename, T content) {
        /*// 格式化路径字符串
        dirs = dirs.replace("\\", "/");*/
        // 设置目录路径
        Path dirspath = Paths.get(dirs);
        // 设置文件保存路径
        Path filepath = Paths.get(dirs, filename + ".txt");

        try {
            // 判断目录路径是否存在
            if (!Files.exists(dirspath))
                Files.createDirectories(dirspath);

            // 判断文件路径是否存在
            if (!Files.exists(filepath))
                Files.createFile(filepath);
            // 将数据JSON格式化
            String jsonContent = jsonMapper.writeValueAsString(content);
            // 将数据（覆盖）写入文件
            Files.writeString(filepath, jsonContent, StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new OtherException(e.toString());
        }

        return filepath;
    }

    /**
     * 从到指定路径读JSON字符串
     */
    public static <T> T readJson4FilePath(Path filepath, T type) {
        if (!Files.exists(filepath))
            throw new OtherException(OtherExConstant.PATH_NOT_EXISTS + filepath);

        try {
            String jsonCase = Files.readString(filepath, StandardCharsets.UTF_8);
            Object obj = jsonMapper.readValue(jsonCase, type.getClass());

            return (T) obj;
        } catch (Exception e) {
            throw new OtherException(e.toString());
        }
    }

    /**
     * 参数类型转换
     */
    public static Object argvCast(Object argv, Class<?> argvClass) {
        // 从文件中读取时，[]（数组/集合）一般读为（ArrayList）集合
        if (argvClass.equals(int.class)) {
            return Integer.parseInt(argv.toString());
        } else if (argvClass.equals(long.class)) {
            return Long.parseLong(argv.toString());
        } else if (argvClass.equals(double.class)) {
            return Double.parseDouble(argv.toString());
        } else if (argvClass.equals(Integer.class)) {
            return Integer.valueOf(argv.toString());
        } else if (argvClass.equals(Long.class)) {
            return Long.valueOf(argv.toString());
        } else if (argvClass.equals(Double.class)) {
            return Double.valueOf(argv.toString());
        } else if (argvClass.equals(int[].class)) {
            return fromJson(argv.toString(), int[].class);
        } else if (argvClass.equals(long[].class)) {
            return fromJson(argv.toString(), long[].class);
        } else if (argvClass.equals(double[].class)) {
            return fromJson(argv.toString(), double[].class);
        } else if (argvClass.equals(Integer[].class)) {
            return fromJson(argv.toString(), Integer[].class);
        } else if (argvClass.equals(Long[].class)) {
            return fromJson(argv.toString(), Long[].class);
        } else if (argvClass.equals(Double[].class)) {
            return fromJson(argv.toString(), Double[].class);
        } else if (argvClass.equals(String[].class)) {
//            return fromJson(argv.toString(), String[].class);
            return ((List<String>) argv).toArray(new String[0]);
        } else {
            // String ...
            return argvClass.cast(argv);
        }
    }

}
